import os
import subprocess
from shutil import copy
import time
p1_res_path = 'C:\space_war\p1_request.txt'
p2_res_path = 'C:\space_war\p2_request.txt'
game_length = 60*30


def sort_file():
    res_content = "0,0996112,0088024,0\n1,0996112,0088024,2\n0,0"
    res_paths = ["C:\\space_war\\p1_request.txt", "C:\\space_war\\p2_request.txt"]
    for path in res_paths:
        with open(path, 'w') as f:
            f.write(res_content)

def kill_game():
    os.system("powershell \"Get-Process SPACE_WAR* | kill\"")

def is_single(path):
    result = True
    try :
        with open(path, 'r', encoding='utf-8') as f:
            for line in f.readlines():
                line_replaced = line.replace(' ', '')
                if line_replaced.find('#include') != -1 and line_replaced.find('space_war.h') != -1:
                    result = False
                    break
    except UnicodeDecodeError:
        with open(path, 'r') as f:
            for line in f.readlines():
                line_replaced = line.replace(' ', '')
                if line_replaced.find('#include') != -1 and line_replaced.find('space_war.h') != -1:
                    result =  False
                    break
    return result

def is_end(p1_res_path, p2_res_path, time_width = 5, time_max = 60*30):

    win_msg = ["p1 win!", "p2 win!"]
    for i in range((int)(time_max/time_width + 1)):
        # print(time.time())
        with open(p1_res_path, 'r') as f, open(p2_res_path, 'r') as g:
            if f.readline() in win_msg or g.readline() in win_msg:
                return True
        # print(time.time())
        time.sleep(time_width)
        
    return False
class players:
    def __init__(self, file_path, lib_path) -> None:
        self.path = file_path
        self.names = [item for item in os.listdir(file_path) if os.path.splitext(item)[1] == '.c']
        self.__compile(lib_path)
    def __compile(self, lib_path):
        for name in self.names:
            # copy source to lib
            path = os.path.join(self.path, name)
            copy(path, lib_path)
            # compile
            main_file = os.path.join(lib_path, name)
            out_file = os.path.join(self.path, os.path.splitext(name)[0]+'.exe')
            in_file = os.path.join(lib_path, '*.c') if not is_single(os.path.join(self.path, name)) else os.path.join(lib_path, name)
            #error message
            msg_folder = os.path.join(self.path, "compile_msg")
            if  not os.path.exists(msg_folder):
                os.mkdir(msg_folder)
            compile_msg = os.path.join(msg_folder, os.path.splitext(name)[0]+'_compile_msg.txt')
            gcc_cmd = "gcc -g -m64 -Wall -static-libgcc " + ' ' + in_file +' -o ' + out_file +' 2> '+ compile_msg
            os.system(gcc_cmd)
            os.remove(main_file)
            
            # excutable file
            self.exc = [item for item in os.listdir(self.path) if os.path.splitext(item)[1] == '.exe']

            exc_tmp = [os.path.splitext(item)[0] for item in self.exc]
            c_tmp = [os.path.splitext(item)[0] for item in self.names]

            self.err_compile = [item for item in c_tmp if item not in exc_tmp]
    def __game_vs(self, ex1, ex2, game_path,result_path) -> str:
        sort_file()
        ex1_full = os.path.join(self.path, ex1)
        ex2_full = os.path.join(self.path, ex2)

        out_folder = os.path.join(self.path, "output")
        if  not os.path.exists(out_folder):
            os.mkdir(out_folder)
        out_path = os.path.join(out_folder, os.path.splitext(ex1)[0] + '-vs-' + os.path.splitext(ex2)[0])
        if not os.path.exists(out_path):
             os.mkdir(out_path)
        ex1_err = os.path.join(out_path ,os.path.splitext(ex1)[0] + '_stderr.txt')
        ex1_out = os.path.join(out_path ,os.path.splitext(ex1)[0] + '_stdout.txt')
        ex2_err = os.path.join(out_path ,os.path.splitext(ex2)[0] + '_stderr.txt')
        ex2_out = os.path.join(out_path ,os.path.splitext(ex2)[0] + '_stdout.txt')


        with  open(ex1_err, 'w') as err1, open(ex1_out, 'w') as out1,open(ex2_err, 'w') as err2, open(ex2_out, 'w') as out2:
            game = subprocess.Popen(game_path, stdin=subprocess.PIPE)
            p1 = subprocess.Popen([ex1_full, '0'], stdout=out1 ,stderr=err1)
            p2 = subprocess.Popen([ex2_full, '1'], stdout=out2 ,stderr=err2)
            # try:
            #     p1.wait()
            #     p2.wait()
            # except subprocess.TimeoutExpired:
            #     p1.kill()
            #     p2.kill()
            #     # game.kill()
            end_flag = is_end(p1_res_path, p2_res_path, time_max= game_length)
            with open(p1_res_path, 'r') as f, open(p2_res_path, 'r') as g:
                p1_res = list(f.readlines())[0 if end_flag else -1]
                p2_res = list(g.readlines())[0 if end_flag else -1]

            kill_game()
            with open(result_path, 'a') as f:
                f.write(ex1 + ':' + p1_res + ' ' + ex2 + ':' + p2_res + '\n')


        # p1 = Process(target= lambda : os.system())

    def judge(self, game_path, result_path):
        with open(result_path, 'w') as f:
            f.write("\n")
        for i in range(len(self.exc) - 1):
            for j in range(i + 1, len(self.exc)):
                print(self.exc[i] + 'vs'+ self.exc[j] + '\n')
                self.__game_vs(self.exc[i], self.exc[j],game_path, result_path)

        

players_folder = "C:\space_war\space_war\space_war\players"
lib_path = "C:\space_war\space_war\space_war\player1"
game_path = 'C:\space_war\space_war\WindowsNoEditor\SPACE_WAR.exe'
result_path = "C:\space_war\space_war\space_war\players\\result.txt"

players = players(players_folder,lib_path)

print("error compile:")
print(players.err_compile)

players.judge(game_path, result_path)